package com.xspace.android.xafcommon.util;

import android.content.Intent;
import android.net.Uri;
import android.os.Environment;
import android.util.Log;

import com.xspace.android.xafcommon.appliction.BaseApplication;
import com.xspace.android.xafcommon.been.AppInfoBean;
import com.xspace.android.xafcommon.been.DownloadInfo;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;


public class DownloadManager {

    private static final String TAG = DownloadManager.class.getSimpleName();

    //定义下载目录 : /mnt/sdcard/包名/download
    public static String DOWNLOAD_DIR = Environment.getExternalStorageDirectory().getPath() +
            File.separator + "ctnq" + File.separator + "download";


    //定义下载状态常量
    public static final int STATE_NONE = 0;//未下载的状态
    public static final int STATE_DOWNLOADING = 1;//下载中的状态
    public static final int STATE_PAUSE = 2;//暂停的状态
    public static final int STATE_WAITING = 3;//等待中的状态，任务对象已经创建，但是run方法没有执行
    public static final int STATE_FINISH = 4;//下载完成的状态
    public static final int STATE_ERROR = 5;//下载出错的状态

    private static DownloadManager mInstance = new DownloadManager();

    public static synchronized DownloadManager getInstance() {
        return mInstance;
    }

    //用来存放所有界面的监听器对象
//    private ArrayList<DownloadObserver> observerList = new ArrayList<DownloadObserver>();
    private DownloadObserver downloadObserver;

    private DownloadInfo downloadInfo;

    private DownloadManager() {
        //初始化下载目录
        File file = new File(DOWNLOAD_DIR);
        if (!file.exists()) {
            file.mkdirs();
        }
    }

    /**
     * 下载的方法
     */
    public void download(AppInfoBean appInfo) {
        //1.获取下载任务对应的DownloadInfo
        if (downloadInfo == null) {
            //说明该任务从来没有下载过
            downloadInfo = DownloadInfo.create(appInfo);
        }
        //2.获取下载任务对应的state来判断是否能够进行下载: none,pause,error
        int state = downloadInfo.getState();
        Log.e(TAG, "download: " + state);
        if (state == STATE_NONE || state == STATE_PAUSE || state == STATE_ERROR) {
            //说明可以进行下载了,那么就可以创建DownloadTask,交给线程池管理
            DownloadTask downloadTask = new DownloadTask(downloadInfo);

            //更新下载任务对应的state
            downloadInfo.setState(STATE_WAITING);//更新状态为等待中
            //通知监听器状态更改了
            notifyDownloadStateChange(downloadInfo);

            //3.将DownloadTask交给线程池管理
            ThreadPoolManager.getInstance().execute(downloadTask);
        }
    }

    /**
     * 下载文件和保存文件的逻辑都在这里面
     *
     * @author Administrator
     */
    class DownloadTask implements Runnable {
        private DownloadInfo downloadInfo;

        public DownloadTask(DownloadInfo downloadInfo) {
            this.downloadInfo = downloadInfo;
        }

        @Override
        public void run() {
            //4.run方法执行就将state设置downloading
            downloadInfo.setState(STATE_DOWNLOADING);//更新状态为等待中
            //通知监听器状态更改
            notifyDownloadStateChange(downloadInfo);

            //5.判断下载类型：a.从头下载     b.断点下载
            HttpUtils.HttpResult httpResult;
            File file = new File(downloadInfo.getPath());
//            if (!file.exists() || file.length() != downloadInfo.getCurrentLength()) {}
            if (file.exists()) {
                //从头下载的情况
                file.delete();//删除无效文件
                downloadInfo.setCurrentLength(0);//清空currentLength
            }
            httpResult = HttpUtils.download(downloadInfo.getDownloadUrl());

            //6.读取流，写入文件
            if (httpResult != null && httpResult.getInputStream() != null) {
                //说明成功的请求到了文件数据
                InputStream is = httpResult.getInputStream();
                FileOutputStream fos = null;
                try {
                    fos = new FileOutputStream(file, true);
                    byte[] buffer = new byte[1024 * 8];//8k的缓冲区
                    int len;
                    while ((len = is.read(buffer)) != -1 && downloadInfo.getState() == STATE_DOWNLOADING) {
                        fos.write(buffer, 0, len);//写文件

                        //更新currentLength
                        downloadInfo.setCurrentLength(downloadInfo.getCurrentLength() + len);
                        //通知监听器下载进度更新
                        notifyDownloadProgressChange(downloadInfo);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    //属于下载失败的情况
                    processDownloadError(file);
                } finally {
                    //关闭链接和流
                    httpResult.close();
                    try {
                        if (fos != null) fos.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }

                //7.代码走到这里：a.下载完成      b.暂停
                if (downloadInfo.getState() == STATE_DOWNLOADING) {
                    //说明下载完成了
                    downloadInfo.setState(STATE_FINISH);
                    notifyDownloadStateChange(downloadInfo);
                } else if (downloadInfo.getState() == STATE_PAUSE) {
                    notifyDownloadStateChange(downloadInfo);
                }
            } else {
                //说明请求文件数据失败
                processDownloadError(file);
            }

        }

        /**
         * 处理下载失败的情况
         *
         * @param file
         */
        private void processDownloadError(File file) {
            file.delete();//删除失败文件
            downloadInfo.setCurrentLength(0);//清空currentLength
            downloadInfo.setState(STATE_ERROR);//更改状态为error
            notifyDownloadStateChange(downloadInfo);//通知状态更改
        }

    }

    /**
     * 通知所有的监听器状态更改了
     *
     * @param downloadInfo
     */
    private void notifyDownloadStateChange(final DownloadInfo downloadInfo) {
        BaseApplication.getMainHandler().post(new Runnable() {
            @Override
            public void run() {
                if (downloadObserver != null) {
                    downloadObserver.onDownloadStateChange(downloadInfo);
                }
            }
        });
//        CommonUtil.runOnUIThread(new Runnable() {
//            @Override
//            public void run() {
//                for (DownloadObserver observer : observerList) {
//                    observer.onDownloadStateChange(downloadInfo);
//                }
//            }
//        });
    }

    public DownloadInfo getDownloadInfo() {
        return downloadInfo;
    }

    /**
     * 通知所有的监听器下载进度更新了
     *
     * @param downloadInfo
     */
    private void notifyDownloadProgressChange(final DownloadInfo downloadInfo) {
        BaseApplication.getMainHandler().post(new Runnable() {
            @Override
            public void run() {
                if (downloadObserver != null) {
                    downloadObserver.onDownloadProgressChange(downloadInfo);
                }
            }
        });


//        CommonUtil.runOnUIThread(new Runnable() {
//            @Override
//            public void run() {
//                for (DownloadObserver observer : observerList) {
//                    observer.onDownloadProgressChange(downloadInfo);
//                }
//            }
//        });
    }

    /**
     * 暂停的方法
     */
    public void pause(AppInfoBean appInfo) {
        if (downloadInfo != null) {
            //将当前downloadINfo的state设置为pause
            downloadInfo.setState(STATE_PAUSE);//更改状态
            notifyDownloadStateChange(downloadInfo);
        }
    }

    /**
     * 安装app的方法
     */
    public void installApk(AppInfoBean appInfo) {
        Intent intent = new Intent(Intent.ACTION_VIEW);
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);//开启新的任务栈来存放新的Activity
        if (downloadInfo != null) {
            /*<action android:name="android.intent.action.VIEW" />
            <category android:name="android.intent.category.DEFAULT" />
            <data android:scheme="content" />
            <data android:scheme="file" />
            <data android:mimeType="application/vnd.android.package-archive" />*/

            intent.setDataAndType(Uri.parse("file://" + downloadInfo.getPath()), "application/vnd.android" +
                    ".package-archive");
        } else {
            intent.setDataAndType(Uri.parse("file://" + DownloadManager.DOWNLOAD_DIR + File.separator
                    + appInfo.version + ".apk"), "application/vnd.android" +
                    ".package-archive");
        }
        BaseApplication.mInstance.startActivity(intent);
    }

    /**
     * 注册下载观察者
     *
     * @param downloadObserver 注册时传入的downloadObserver
     */
    public void registerDownloadObserver(DownloadObserver downloadObserver) {
        this.downloadObserver = downloadObserver;
//        if (!observerList.contains(downloadObserver)) {
//            observerList.add(downloadObserver);
//        }
    }
//
//    /**
//     * 从集合中移除下载观察者
//     *
//     * @param downloadObserver
//     */
//    public void unregisterDownloadObserver(DownloadObserver downloadObserver) {
//        if (observerList.contains(downloadObserver)) {
//            observerList.remove(downloadObserver);
//        }
//    }


    /**
     * 下载状态和进度改变的监听器
     *
     * @author Administrator
     */
    public interface DownloadObserver {
        /**
         * 下载状态改变的回调
         */
        void onDownloadStateChange(DownloadInfo downloadInfo);

        /**
         * 下载进度改变的回调
         */
        void onDownloadProgressChange(DownloadInfo downloadInfo);
    }

}
